// use crate::constants::SpongeConstants;
// use crate::permutation::{full_round, poseidon_block_cipher};
use ark_ff::Field;
use mina_curves::pasta::Fq;
use mina_hasher::Fp;
use once_cell::sync::Lazy;

use std::str::FromStr;

#[cfg(not(target_family = "wasm"))]
mod fp;

mod fq_params;

pub use fq_params::*;

pub fn make_params() -> ArithmeticSpongeParams<Fp> {
    ArithmeticSpongeParams {
        mds: [
            [
                Fp::from_str(
                    "12035446894107573964500871153637039653510326950134440362813193268448863222019",
                )
                .unwrap(),
                Fp::from_str(
                    "25461374787957152039031444204194007219326765802730624564074257060397341542093",
                )
                .unwrap(),
                Fp::from_str(
                    "27667907157110496066452777015908813333407980290333709698851344970789663080149",
                )
                .unwrap(),
            ],
            [
                Fp::from_str(
                    "4491931056866994439025447213644536587424785196363427220456343191847333476930",
                )
                .unwrap(),
                Fp::from_str(
                    "14743631939509747387607291926699970421064627808101543132147270746750887019919",
                )
                .unwrap(),
                Fp::from_str(
                    "9448400033389617131295304336481030167723486090288313334230651810071857784477",
                )
                .unwrap(),
            ],
            [
                Fp::from_str(
                    "10525578725509990281643336361904863911009900817790387635342941550657754064843",
                )
                .unwrap(),
                Fp::from_str(
                    "27437632000253211280915908546961303399777448677029255413769125486614773776695",
                )
                .unwrap(),
                Fp::from_str(
                    "27566319851776897085443681456689352477426926500749993803132851225169606086988",
                )
                .unwrap(),
            ],
        ],

        round_constants: [
            [
                Fp::from_str(
                    "21155079691556475130150866428468322463125560312786319980770950159250751855431",
                )
                .unwrap(),
                Fp::from_str(
                    "16883442198399350202652499677723930673110172289234921799701652810789093522349",
                )
                .unwrap(),
                Fp::from_str(
                    "17030687036425314703519085065002231920937594822150793091243263847382891822670",
                )
                .unwrap(),
            ],
            [
                Fp::from_str(
                    "25216718237129482752721276445368692059997901880654047883630276346421457427360",
                )
                .unwrap(),
                Fp::from_str(
                    "9054264347380455706540423067244764093107767235485930776517975315876127782582",
                )
                .unwrap(),
                Fp::from_str(
                    "26439087121446593160953570192891907825526260324480347638727375735543609856888",
                )
                .unwrap(),
            ],
            [
                Fp::from_str(
                    "15251000790817261169639394496851831733819930596125214313084182526610855787494",
                )
                .unwrap(),
                Fp::from_str(
                    "10861916012597714684433535077722887124099023163589869801449218212493070551767",
                )
                .unwrap(),
                Fp::from_str(
                    "18597653523270601187312528478986388028263730767495975370566527202946430104139",
                )
                .unwrap(),
            ],
            [
                Fp::from_str(
                    "15831416454198644276563319006805490049460322229057756462580029181847589006611",
                )
                .unwrap(),
                Fp::from_str(
                    "15171856919255965617705854914448645702014039524159471542852132430360867202292",
                )
                .unwrap(),
                Fp::from_str(
                    "15488495958879593647482715143904752785889816789652405888927117106448507625751",
                )
                .unwrap(),
            ],
            [
                Fp::from_str(
                    "19039802679983063488134304670998725949842655199289961967801223969839823940152",
                )
                .unwrap(),
                Fp::from_str(
                    "4720101937153217036737330058775388037616286510783561045464678919473230044408",
                )
                .unwrap(),
                Fp::from_str(
                    "10226318327254973427513859412126640040910264416718766418164893837597674300190",
                )
                .unwrap(),
            ],
            [
                Fp::from_str(
                    "20878756131129218406920515859235137275859844638301967889441262030146031838819",
                )
                .unwrap(),
                Fp::from_str(
                    "7178475685651744631172532830973371642652029385893667810726019303466125436953",
                )
                .unwrap(),
                Fp::from_str(
                    "1996970955918516145107673266490486752153434673064635795711751450164177339618",
                )
                .unwrap(),
            ],
            [
                Fp::from_str(
                    "15205545916434157464929420145756897321482314798910153575340430817222504672630",
                )
                .unwrap(),
                Fp::from_str(
                    "25660296961552699573824264215804279051322332899472350724416657386062327210698",
                )
                .unwrap(),
                Fp::from_str(
                    "13842611741937412200312851417353455040950878279339067816479233688850376089318",
                )
                .unwrap(),
            ],
            [
                Fp::from_str(
                    "1383799642177300432144836486981606294838630135265094078921115713566691160459",
                )
                .unwrap(),
                Fp::from_str(
                    "1135532281155277588005319334542025976079676424839948500020664227027300010929",
                )
                .unwrap(),
                Fp::from_str(
                    "4384117336930380014868572224801371377488688194169758696438185377724744869360",
                )
                .unwrap(),
            ],
            [
                Fp::from_str(
                    "21725577575710270071808882335900370909424604447083353471892004026180492193649",
                )
                .unwrap(),
                Fp::from_str(
                    "676128913284806802699862508051022306366147359505124346651466289788974059668",
                )
                .unwrap(),
                Fp::from_str(
                    "25186611339598418732666781049829183886812651492845008333418424746493100589207",
                )
                .unwrap(),
            ],
            [
                Fp::from_str(
                    "10402240124664763733060094237696964473609580414190944671778761753887884341073",
                )
                .unwrap(),
                Fp::from_str(
                    "11918307118590866200687906627767559273324023585642003803337447146531313172441",
                )
                .unwrap(),
                Fp::from_str(
                    "16895677254395661024186292503536662354181715337630376909778003268311296637301",
                )
                .unwrap(),
            ],
            [
                Fp::from_str(
                    "23818602699032741669874498456696325705498383130221297580399035778119213224810",
                )
                .unwrap(),
                Fp::from_str(
                    "4285193711150023248690088154344086684336247475445482883105661485741762600154",
                )
                .unwrap(),
                Fp::from_str(
                    "19133204443389422404056150665863951250222934590192266371578950735825153238612",
                )
                .unwrap(),
            ],
            [
                Fp::from_str(
                    "5515589673266504033533906836494002702866463791762187140099560583198974233395",
                )
                .unwrap(),
                Fp::from_str(
                    "11830435563729472715615302060564876527985621376031612798386367965451821182352",
                )
                .unwrap(),
                Fp::from_str(
                    "7510711479224915247011074129666445216001563200717943545636462819681638560128",
                )
                .unwrap(),
            ],
            [
                Fp::from_str(
                    "24694843201907722940091503626731830056550128225297370217610328578733387733444",
                )
                .unwrap(),
                Fp::from_str(
                    "27361655066973784653563425664091383058914302579694897188019422193564924110528",
                )
                .unwrap(),
                Fp::from_str(
                    "21606788186194534241166833954371013788633495786419718955480491478044413102713",
                )
                .unwrap(),
            ],
            [
                Fp::from_str(
                    "19934060063390905409309407607814787335159021816537006003398035237707924006757",
                )
                .unwrap(),
                Fp::from_str(
                    "8495813630060004961768092461554180468161254914257386012937942498774724649553",
                )
                .unwrap(),
                Fp::from_str(
                    "27524960680529762202005330464726908693944660961000958842417927307941561848461",
                )
                .unwrap(),
            ],
            [
                Fp::from_str(
                    "15178481650950399259757805400615635703086255035073919114667254549690862896985",
                )
                .unwrap(),
                Fp::from_str(
                    "16164780354695672259791105197274509251141405713012804937107314962551600380870",
                )
                .unwrap(),
                Fp::from_str(
                    "10529167793600778056702353412758954281652843049850979705476598375597148191979",
                )
                .unwrap(),
            ],
            [
                Fp::from_str(
                    "721141070179074082553302896292167103755384741083338957818644728290501449040",
                )
                .unwrap(),
                Fp::from_str(
                    "22044408985956234023934090378372374883099115753118261312473550998188148912041",
                )
                .unwrap(),
                Fp::from_str(
                    "27068254103241989852888872162525066148367014691482601147536314217249046186315",
                )
                .unwrap(),
            ],
            [
                Fp::from_str(
                    "3880429241956357176819112098792744584376727450211873998699580893624868748961",
                )
                .unwrap(),
                Fp::from_str(
                    "17387097125522937623262508065966749501583017524609697127088211568136333655623",
                )
                .unwrap(),
                Fp::from_str(
                    "6256814421247770895467770393029354017922744712896100913895513234184920631289",
                )
                .unwrap(),
            ],
            [
                Fp::from_str(
                    "2942627347777337187690939671601251987500285937340386328746818861972711408579",
                )
                .unwrap(),
                Fp::from_str(
                    "24031654937764287280548628128490074801809101323243546313826173430897408945397",
                )
                .unwrap(),
                Fp::from_str(
                    "14401457902976567713827506689641442844921449636054278900045849050301331732143",
                )
                .unwrap(),
            ],
            [
                Fp::from_str(
                    "20170632877385406450742199836933900257692624353889848352407590794211839130727",
                )
                .unwrap(),
                Fp::from_str(
                    "24056496193857444725324410428861722338174099794084586764867109123681727290181",
                )
                .unwrap(),
                Fp::from_str(
                    "11257913009612703357266904349759250619633397075667824800196659858304604714965",
                )
                .unwrap(),
            ],
            [
                Fp::from_str(
                    "22228158921984425749199071461510152694025757871561406897041788037116931009246",
                )
                .unwrap(),
                Fp::from_str(
                    "9152163378317846541430311327336774331416267016980485920222768197583559318682",
                )
                .unwrap(),
                Fp::from_str(
                    "13906695403538884432896105059360907560653506400343268230130536740148070289175",
                )
                .unwrap(),
            ],
            [
                Fp::from_str(
                    "7220714562509721437034241786731185291972496952091254931195414855962344025067",
                )
                .unwrap(),
                Fp::from_str(
                    "27608867305903811397208862801981345878179337369367554478205559689592889691927",
                )
                .unwrap(),
                Fp::from_str(
                    "13288465747219756218882697408422850918209170830515545272152965967042670763153",
                )
                .unwrap(),
            ],
            [
                Fp::from_str(
                    "8251343892709140154567051772980662609566359215743613773155065627504813327653",
                )
                .unwrap(),
                Fp::from_str(
                    "22035238365102171608166944627493632660244312563934708756134297161332908879090",
                )
                .unwrap(),
                Fp::from_str(
                    "13560937766273321037807329177749403409731524715067067740487246745322577571823",
                )
                .unwrap(),
            ],
            [
                Fp::from_str(
                    "21652518608959234550262559135285358020552897349934571164032339186996805408040",
                )
                .unwrap(),
                Fp::from_str(
                    "22479086963324173427634460342145551255011746993910136574926173581069603086891",
                )
                .unwrap(),
                Fp::from_str(
                    "13676501958531751140966255121288182631772843001727158043704693838707387130095",
                )
                .unwrap(),
            ],
            [
                Fp::from_str(
                    "5680310394102577950568930199056707827608275306479994663197187031893244826674",
                )
                .unwrap(),
                Fp::from_str(
                    "25125360450906166639190392763071557410047335755341060350879819485506243289998",
                )
                .unwrap(),
                Fp::from_str(
                    "22659254028501616785029594492374243581602744364859762239504348429834224676676",
                )
                .unwrap(),
            ],
            [
                Fp::from_str(
                    "23101411405087512171421838856759448177512679869882987631073569441496722536782",
                )
                .unwrap(),
                Fp::from_str(
                    "24149774013240355952057123660656464942409328637280437515964899830988178868108",
                )
                .unwrap(),
                Fp::from_str(
                    "5782097512368226173095183217893826020351125522160843964147125728530147423065",
                )
                .unwrap(),
            ],
            [
                Fp::from_str(
                    "13540762114500083869920564649399977644344247485313990448129838910231204868111",
                )
                .unwrap(),
                Fp::from_str(
                    "20421637734328811337527547703833013277831804985438407401987624070721139913982",
                )
                .unwrap(),
                Fp::from_str(
                    "7742664118615900772129122541139124149525273579639574972380600206383923500701",
                )
                .unwrap(),
            ],
            [
                Fp::from_str(
                    "1109643801053963021778418773196543643970146666329661268825691230294798976318",
                )
                .unwrap(),
                Fp::from_str(
                    "16580663920817053843121063692728699890952505074386761779275436996241901223840",
                )
                .unwrap(),
                Fp::from_str(
                    "14638514680222429058240285918830106208025229459346033470787111294847121792366",
                )
                .unwrap(),
            ],
            [
                Fp::from_str(
                    "17080385857812672649489217965285727739557573467014392822992021264701563205891",
                )
                .unwrap(),
                Fp::from_str(
                    "26176268111736737558502775993925696791974738793095023824029827577569530708665",
                )
                .unwrap(),
                Fp::from_str(
                    "4382756253392449071896813428140986330161215829425086284611219278674857536001",
                )
                .unwrap(),
            ],
            [
                Fp::from_str(
                    "13934033814940585315406666445960471293638427404971553891617533231178815348902",
                )
                .unwrap(),
                Fp::from_str(
                    "27054912732979753314774418228399230433963143177662848084045249524271046173121",
                )
                .unwrap(),
                Fp::from_str(
                    "28916070403698593376490976676534962592542013020010643734621202484860041243391",
                )
                .unwrap(),
            ],
            [
                Fp::from_str(
                    "24820015636966360150164458094894587765384135259446295278101998130934963922381",
                )
                .unwrap(),
                Fp::from_str(
                    "7969535238488580655870884015145760954416088335296905520306227531221721881868",
                )
                .unwrap(),
                Fp::from_str(
                    "7690547696740080985104189563436871930607055124031711216224219523236060212249",
                )
                .unwrap(),
            ],
            [
                Fp::from_str(
                    "9712576468091272384496248353414290908377825697488757134833205246106605867289",
                )
                .unwrap(),
                Fp::from_str(
                    "12148698031438398980683630141370402088785182722473169207262735228500190477924",
                )
                .unwrap(),
                Fp::from_str(
                    "14359657643133476969781351728574842164124292705609900285041476162075031948227",
                )
                .unwrap(),
            ],
            [
                Fp::from_str(
                    "23563839965372067275137992801035780013422228997724286060975035719045352435470",
                )
                .unwrap(),
                Fp::from_str(
                    "4184634822776323233231956802962638484057536837393405750680645555481330909086",
                )
                .unwrap(),
                Fp::from_str(
                    "16249511905185772125762038789038193114431085603985079639889795722501216492487",
                )
                .unwrap(),
            ],
            [
                Fp::from_str(
                    "11001863048692031559800673473526311616702863826063550559568315794438941516621",
                )
                .unwrap(),
                Fp::from_str(
                    "4702354107983530219070178410740869035350641284373933887080161024348425080464",
                )
                .unwrap(),
                Fp::from_str(
                    "23751680507533064238793742311430343910720206725883441625894258483004979501613",
                )
                .unwrap(),
            ],
            [
                Fp::from_str(
                    "28670526516158451470169873496541739545860177757793329093045522432279094518766",
                )
                .unwrap(),
                Fp::from_str(
                    "3568312993091537758218792253361873752799472566055209125947589819564395417072",
                )
                .unwrap(),
                Fp::from_str(
                    "1819755756343439646550062754332039103654718693246396323207323333948654200950",
                )
                .unwrap(),
            ],
            [
                Fp::from_str(
                    "5372129954699791301953948907349887257752247843844511069896766784624930478273",
                )
                .unwrap(),
                Fp::from_str(
                    "17512156688034945920605615850550150476471921176481039715733979181538491476080",
                )
                .unwrap(),
                Fp::from_str(
                    "25777105342317622165159064911913148785971147228777677435200128966844208883059",
                )
                .unwrap(),
            ],
            [
                Fp::from_str(
                    "25350392006158741749134238306326265756085455157012701586003300872637887157982",
                )
                .unwrap(),
                Fp::from_str(
                    "20096724945283767296886159120145376967480397366990493578897615204296873954844",
                )
                .unwrap(),
                Fp::from_str(
                    "8063283381910110762785892100479219642751540456251198202214433355775540036851",
                )
                .unwrap(),
            ],
            [
                Fp::from_str(
                    "4393613870462297385565277757207010824900723217720226130342463666351557475823",
                )
                .unwrap(),
                Fp::from_str(
                    "9874972555132910032057499689351411450892722671352476280351715757363137891038",
                )
                .unwrap(),
                Fp::from_str(
                    "23590926474329902351439438151596866311245682682435235170001347511997242904868",
                )
                .unwrap(),
            ],
            [
                Fp::from_str(
                    "17723373371137275859467518615551278584842947963894791032296774955869958211070",
                )
                .unwrap(),
                Fp::from_str(
                    "2350345015303336966039836492267992193191479606566494799781846958620636621159",
                )
                .unwrap(),
                Fp::from_str(
                    "27755207882790211140683010581856487965587066971982625511152297537534623405016",
                )
                .unwrap(),
            ],
            [
                Fp::from_str(
                    "6584607987789185408123601849106260907671314994378225066806060862710814193906",
                )
                .unwrap(),
                Fp::from_str(
                    "609759108847171587253578490536519506369136135254150754300671591987320319770",
                )
                .unwrap(),
                Fp::from_str(
                    "28435187585965602110074342250910608316032945187476441868666714022529803033083",
                )
                .unwrap(),
            ],
            [
                Fp::from_str(
                    "16016664911651770663938916450245705908287192964254704641717751103464322455303",
                )
                .unwrap(),
                Fp::from_str(
                    "17551273293154696089066968171579395800922204266630874071186322718903959339163",
                )
                .unwrap(),
                Fp::from_str(
                    "20414195497994754529479032467015716938594722029047207834858832838081413050198",
                )
                .unwrap(),
            ],
            [
                Fp::from_str(
                    "19773307918850685463180290966774465805537520595602496529624568184993487593855",
                )
                .unwrap(),
                Fp::from_str(
                    "24598603838812162820757838364185126333280131847747737533989799467867231166980",
                )
                .unwrap(),
                Fp::from_str(
                    "11040972566103463398651864390163813377135738019556270484707889323659789290225",
                )
                .unwrap(),
            ],
            [
                Fp::from_str(
                    "5189242080957784038860188184443287562488963023922086723850863987437818393811",
                )
                .unwrap(),
                Fp::from_str(
                    "1435203288979376557721239239445613396009633263160237764653161500252258220144",
                )
                .unwrap(),
                Fp::from_str(
                    "13066591163578079667911016543985168493088721636164837520689376346534152547210",
                )
                .unwrap(),
            ],
            [
                Fp::from_str(
                    "17345901407013599418148210465150865782628422047458024807490502489711252831342",
                )
                .unwrap(),
                Fp::from_str(
                    "22139633362249671900128029132387275539363684188353969065288495002671733200348",
                )
                .unwrap(),
                Fp::from_str(
                    "1061056418502836172283188490483332922126033656372467737207927075184389487061",
                )
                .unwrap(),
            ],
            [
                Fp::from_str(
                    "10241738906190857416046229928455551829189196941239601756375665129874835232299",
                )
                .unwrap(),
                Fp::from_str(
                    "27808033332417845112292408673209999320983657696373938259351951416571545364415",
                )
                .unwrap(),
                Fp::from_str(
                    "18820154989873674261497645724903918046694142479240549687085662625471577737140",
                )
                .unwrap(),
            ],
            [
                Fp::from_str(
                    "7983688435214640842673294735439196010654951226956101271763849527529940619307",
                )
                .unwrap(),
                Fp::from_str(
                    "17067928657801807648925755556866676899145460770352731818062909643149568271566",
                )
                .unwrap(),
                Fp::from_str(
                    "24472070825156236829515738091791182856425635433388202153358580534810244942762",
                )
                .unwrap(),
            ],
            [
                Fp::from_str(
                    "25752201169361795911258625731016717414310986450004737514595241038036936283227",
                )
                .unwrap(),
                Fp::from_str(
                    "26041505376284666160132119888949817249574689146924196064963008712979256107535",
                )
                .unwrap(),
                Fp::from_str(
                    "23977050489096115210391718599021827780049209314283111721864956071820102846008",
                )
                .unwrap(),
            ],
            [
                Fp::from_str(
                    "26678257097278788410676026718736087312816016749016738933942134600725962413805",
                )
                .unwrap(),
                Fp::from_str(
                    "10480026985951498884090911619636977502506079971893083605102044931823547311729",
                )
                .unwrap(),
                Fp::from_str(
                    "21126631300593007055117122830961273871167754554670317425822083333557535463396",
                )
                .unwrap(),
            ],
            [
                Fp::from_str(
                    "1564862894215434177641156287699106659379648851457681469848362532131406827573",
                )
                .unwrap(),
                Fp::from_str(
                    "13247162472821152334486419054854847522301612781818744556576865965657773174584",
                )
                .unwrap(),
                Fp::from_str(
                    "8673615954922496961704442777870253767001276027366984739283715623634850885984",
                )
                .unwrap(),
            ],
            [
                Fp::from_str(
                    "2794525076937490807476666942602262298677291735723129868457629508555429470085",
                )
                .unwrap(),
                Fp::from_str(
                    "4656175953888995612264371467596648522808911819700660048695373348629527757049",
                )
                .unwrap(),
                Fp::from_str(
                    "23221574237857660318443567292601561932489621919104226163978909845174616477329",
                )
                .unwrap(),
            ],
            [
                Fp::from_str(
                    "1878392460078272317716114458784636517603142716091316893054365153068227117145",
                )
                .unwrap(),
                Fp::from_str(
                    "2370412714505757731457251173604396662292063533194555369091306667486647634097",
                )
                .unwrap(),
                Fp::from_str(
                    "17409784861870189930766639925394191888667317762328427589153989811980152373276",
                )
                .unwrap(),
            ],
            [
                Fp::from_str(
                    "25869136641898166514111941708608048269584233242773814014385564101168774293194",
                )
                .unwrap(),
                Fp::from_str(
                    "11361209360311194794795494027949518465383235799633128250259863567683341091323",
                )
                .unwrap(),
                Fp::from_str(
                    "14913258820718821235077379851098720071902170702113538811112331615559409988569",
                )
                .unwrap(),
            ],
            [
                Fp::from_str(
                    "12957012022018304419868287033513141736995211906682903915897515954290678373899",
                )
                .unwrap(),
                Fp::from_str(
                    "17128889547450684566010972445328859295804027707361763477802050112063630550300",
                )
                .unwrap(),
                Fp::from_str(
                    "23329219085372232771288306767242735245018143857623151155581182779769305489903",
                )
                .unwrap(),
            ],
            [
                Fp::from_str(
                    "1607741027962933685476527275858938699728586794398382348454736018784568853937",
                )
                .unwrap(),
                Fp::from_str(
                    "2611953825405141009309433982109911976923326848135736099261873796908057448476",
                )
                .unwrap(),
                Fp::from_str(
                    "7372230383134982628913227482618052530364724821976589156840317933676130378411",
                )
                .unwrap(),
            ],
            [
                Fp::from_str(
                    "20203606758501212620842735123770014952499754751430660463060696990317556818571",
                )
                .unwrap(),
                Fp::from_str(
                    "4678361398979174017885631008335559529633853759463947250620930343087749944307",
                )
                .unwrap(),
                Fp::from_str(
                    "27176462634198471376002287271754121925750749676999036165457559387195124025594",
                )
                .unwrap(),
            ],
            [
                Fp::from_str(
                    "6361981813552614697928697527332318530502852015189048838072565811230204474643",
                )
                .unwrap(),
                Fp::from_str(
                    "13815234633287489023151647353581705241145927054858922281829444557905946323248",
                )
                .unwrap(),
                Fp::from_str(
                    "10888828634279127981352133512429657747610298502219125571406085952954136470354",
                )
                .unwrap(),
            ],
        ],
    }
}

/// the fp sponge params
pub fn static_params() -> &'static ArithmeticSpongeParams<Fp> {
    static PARAMS: Lazy<ArithmeticSpongeParams<Fp>> = Lazy::new(make_params);
    &PARAMS
}

pub fn make_fq_params() -> ArithmeticSpongeParams<Fq> {
    ArithmeticSpongeParams {
        mds: [
            [
                Fq::from_str(
                    "28115781186772277486790024060542467295096710153315236019619365740021995624782",
                )
                .unwrap(),
                Fq::from_str(
                    "22098002279041163367053200604969603243328318626084412751290336872362628294144",
                )
                .unwrap(),
                Fq::from_str(
                    "10518156075882958317589806716220047551309200159506906232124952575033472931386",
                )
                .unwrap(),
            ],
            [
                Fq::from_str(
                    "8515206633865386306014865142947895502833797732365705727001733785057042819852",
                )
                .unwrap(),
                Fq::from_str(
                    "19310731234716792175834594131802557577955166208124819468043130037927500684373",
                )
                .unwrap(),
                Fq::from_str(
                    "361439796332338311597104753147071943681730695313819021679602959964518909239",
                )
                .unwrap(),
            ],
            [
                Fq::from_str(
                    "2193808570710678216879007026210418088296432071066284289131688133644970611483",
                )
                .unwrap(),
                Fq::from_str(
                    "1201496953174589855481629688627002262719699487577300614284420648015658009380",
                )
                .unwrap(),
                Fq::from_str(
                    "11619800255560837597192574795389782851917036920101027584480912719351481334717",
                )
                .unwrap(),
            ],
        ],
        round_constants: [
            [
                Fq::from_str(
                    "2517640872121921965298496967863234221143680281046699148760560696057284005606",
                )
                .unwrap(),
                Fq::from_str(
                    "3391756047431116221709518926936538303706203177575259437741546230828058541679",
                )
                .unwrap(),
                Fq::from_str(
                    "28193080211857729746868575888309975056941007202713113547154010421664334143056",
                )
                .unwrap(),
            ],
            [
                Fq::from_str(
                    "25261619184426186938919514618416881383323154981235406731208902193655587998749",
                )
                .unwrap(),
                Fq::from_str(
                    "5438499261516835502981531641588657477212528137520578797088407969732830437134",
                )
                .unwrap(),
                Fq::from_str(
                    "1447697894671779324954748568939217281372628544919576009518449387265606369859",
                )
                .unwrap(),
            ],
            [
                Fq::from_str(
                    "5035532530235542599906399941203951970682478985022204457211063504597080640029",
                )
                .unwrap(),
                Fq::from_str(
                    "18548939393800290417015907795270784249198528773378593112394621615021029911007",
                )
                .unwrap(),
                Fq::from_str(
                    "28314657632459005492203969796973258399484591559931227050853551342156833947891",
                )
                .unwrap(),
            ],
            [
                Fq::from_str(
                    "10075465805557971120845970058070916255338843492716768289922460436606689369477",
                )
                .unwrap(),
                Fq::from_str(
                    "21985996556868691161386211003270106475915714625334030557267947035839814254081",
                )
                .unwrap(),
                Fq::from_str(
                    "9778523497398309788873186849997676949503189428912377745814036481347657299161",
                )
                .unwrap(),
            ],
            [
                Fq::from_str(
                    "6085447467925843146276340167082679235758707259098174769103982431882228334038",
                )
                .unwrap(),
                Fq::from_str(
                    "11214803418623679719680560978819619149235769633101428825693192995405955507848",
                )
                .unwrap(),
                Fq::from_str(
                    "20585482519401972421539035665320299097144487427998598740316244173221216198246",
                )
                .unwrap(),
            ],
            [
                Fq::from_str(
                    "18602266896623204184748247002001496873223612100325866696399863661914256384486",
                )
                .unwrap(),
                Fq::from_str(
                    "22165919841309962137671309308234475433816142848229812860682345190836583925843",
                )
                .unwrap(),
                Fq::from_str(
                    "22833505632200982123686653495190412951871851216487329681987951602744930627412",
                )
                .unwrap(),
            ],
            [
                Fq::from_str(
                    "200996541962081036547810490655955282117589336000744078845964972887355639644",
                )
                .unwrap(),
                Fq::from_str(
                    "17159390488590225463405148524511348095493761844950655304775985535830170165304",
                )
                .unwrap(),
                Fq::from_str(
                    "7519689807382250126180254188667761476713509751388558140260305473388567529705",
                )
                .unwrap(),
            ],
            [
                Fq::from_str(
                    "14159331841037307097148990917607709903712709092721125605507719995418592745663",
                )
                .unwrap(),
                Fq::from_str(
                    "10490695046555645615062072066940833278139280813429718770298136076375411280286",
                )
                .unwrap(),
                Fq::from_str(
                    "9996921069626538041923613626115903019578182147993504053879837245826104687293",
                )
                .unwrap(),
            ],
            [
                Fq::from_str(
                    "28009241574980093348462093077828465154604666812509186537490618830383877236685",
                )
                .unwrap(),
                Fq::from_str(
                    "18925279443828804264179873719494108834579217607847079902207023181925588871175",
                )
                .unwrap(),
                Fq::from_str(
                    "13126164514615718686767880517156253918404905174962666942976286681458411835722",
                )
                .unwrap(),
            ],
            [
                Fq::from_str(
                    "1125667389564136291825905670957082668987611691949011617627091942772124917554",
                )
                .unwrap(),
                Fq::from_str(
                    "12737072162917928935765906421286553437026542524142430058538254259863452556200",
                )
                .unwrap(),
                Fq::from_str(
                    "9855113244149548216327019561589719324434080884827484555441182992249251832158",
                )
                .unwrap(),
            ],
            [
                Fq::from_str(
                    "6006604346195593001833550983798183088851044846011297061071167569148810544010",
                )
                .unwrap(),
                Fq::from_str(
                    "23783465709464699444911580329342599880163107932561352210466223087637763994288",
                )
                .unwrap(),
                Fq::from_str(
                    "1581060363083815351710754851350813999229829634252940169154424073664057276774",
                )
                .unwrap(),
            ],
            [
                Fq::from_str(
                    "24121961545310887440574053281799796355427122479626872394472157625455666323022",
                )
                .unwrap(),
                Fq::from_str(
                    "23925781309638869606256007860000699567158045595326122474217734988331349678475",
                )
                .unwrap(),
                Fq::from_str(
                    "433512980570318160778040929743715681206456334448542248765142091911433454703",
                )
                .unwrap(),
            ],
            [
                Fq::from_str(
                    "8080307140515367021419180108267113624095868360927897204642243727009503935719",
                )
                .unwrap(),
                Fq::from_str(
                    "13661807750191096117929173962837770733539092996971801228126331071941306856508",
                )
                .unwrap(),
                Fq::from_str(
                    "9268394414065063505331314418649987795374055416089324253185088859000252370756",
                )
                .unwrap(),
            ],
            [
                Fq::from_str(
                    "22374115023493407761095751712373350824513305398485824175669182288521610150311",
                )
                .unwrap(),
                Fq::from_str(
                    "22951274634403942446739133926874770994604864227598567536319143390467218980824",
                )
                .unwrap(),
                Fq::from_str(
                    "21411532836345163980832919797897483979345524322135010935120723250070247464549",
                )
                .unwrap(),
            ],
            [
                Fq::from_str(
                    "20688285497159372157224857370703211924056803904697620218749985029000049442943",
                )
                .unwrap(),
                Fq::from_str(
                    "8350087190167057556241775495760369408781696125331535735138679647687106863977",
                )
                .unwrap(),
                Fq::from_str(
                    "13485893160159637778707269611856683957779710980787754997470728774769162419576",
                )
                .unwrap(),
            ],
            [
                Fq::from_str(
                    "4621792784192688819920303666439776744566536330750316034321950771579978771021",
                )
                .unwrap(),
                Fq::from_str(
                    "13900656491552343190424687336475573267660717627286734246676255663734655019912",
                )
                .unwrap(),
                Fq::from_str(
                    "16577037405341365304416318048187907895286388691199320947077947552959834207823",
                )
                .unwrap(),
            ],
            [
                Fq::from_str(
                    "17453637937712580666297652202332273322112052411250919589546137386514183913993",
                )
                .unwrap(),
                Fq::from_str(
                    "9852736110707561006399582579453396957225552488023642073454517393228764176471",
                )
                .unwrap(),
                Fq::from_str(
                    "8053970357622019747109700798952789019805031210730923951116580579194625334710",
                )
                .unwrap(),
            ],
            [
                Fq::from_str(
                    "14566849926060034944494603512439278530775668595134329897253012222562109882008",
                )
                .unwrap(),
                Fq::from_str(
                    "8863944349051942080060073891691580009950648437676309749771884964336231381737",
                )
                .unwrap(),
                Fq::from_str(
                    "16455762285584757654310476505019438984453107876908065440396394186006196612077",
                )
                .unwrap(),
            ],
            [
                Fq::from_str(
                    "28098375311516838082882166381119795701982164671360574802728073046992978741339",
                )
                .unwrap(),
                Fq::from_str(
                    "13538346067341652694825445642847479918140731375902310280683284825070643960891",
                )
                .unwrap(),
                Fq::from_str(
                    "18313412784975078534612748781201087502203257054025866271209086293337241477805",
                )
                .unwrap(),
            ],
            [
                Fq::from_str(
                    "24807061345703288899043018750567607387907450632666147403804744880717736838940",
                )
                .unwrap(),
                Fq::from_str(
                    "16638378638176552952794487891875614248110181610295183306789394461536640085108",
                )
                .unwrap(),
                Fq::from_str(
                    "2342874860138849081032934096750004917991517717553229739958552529472431319656",
                )
                .unwrap(),
            ],
            [
                Fq::from_str(
                    "21631810094765090996871180483650934431972930909326270651252393395613356531282",
                )
                .unwrap(),
                Fq::from_str(
                    "2220759912186713489010197903069023809260408491503960321105305330086947471014",
                )
                .unwrap(),
                Fq::from_str(
                    "14815764944505758746761442212662459585220143243155504464852948007238083120696",
                )
                .unwrap(),
            ],
            [
                Fq::from_str(
                    "23947619952183462858644581465494050309407721428302029371055887418452994318961",
                )
                .unwrap(),
                Fq::from_str(
                    "25035254658153233628169609451068923631269927394392748023889572264723092874720",
                )
                .unwrap(),
                Fq::from_str(
                    "17468020412163678868776493601957969748197290347006692843306595815987772942732",
                )
                .unwrap(),
            ],
            [
                Fq::from_str(
                    "15262198027618900223004625662874755104828479630165814039838611768431063172994",
                )
                .unwrap(),
                Fq::from_str(
                    "25161066724266754383358798644805908588326959881061318668106454787543611445887",
                )
                .unwrap(),
                Fq::from_str(
                    "2454250001039770891411267760383268680504653332090622148533496270387793031332",
                )
                .unwrap(),
            ],
            [
                Fq::from_str(
                    "9171946491887082474979985164918822959719377078284664312866368737511724712644",
                )
                .unwrap(),
                Fq::from_str(
                    "6672870238005411132577302023934139592378291207852994424857452575898007687159",
                )
                .unwrap(),
                Fq::from_str(
                    "2950400608762766076731526167833938554190979516192019010641815746350334547745",
                )
                .unwrap(),
            ],
            [
                Fq::from_str(
                    "10653725154501691589476837895400001173933804810435931645261606197625601363132",
                )
                .unwrap(),
                Fq::from_str(
                    "12717400214508961810851553873706609743505640660238109459222577386574996883747",
                )
                .unwrap(),
                Fq::from_str(
                    "5871058785976817081042949511195036111847495052209270758342334312740290470200",
                )
                .unwrap(),
            ],
            [
                Fq::from_str(
                    "18192562665205900830717234913238180302424621739145466326708104656354353538015",
                )
                .unwrap(),
                Fq::from_str(
                    "19946412409172091711185698839696950657650658896270607012902209489827790455314",
                )
                .unwrap(),
                Fq::from_str(
                    "21997416257528392077410699901606794827305154904508120972585193876767785262539",
                )
                .unwrap(),
            ],
            [
                Fq::from_str(
                    "16525092684784199198745517563091041705366544303388462641935777835264970071331",
                )
                .unwrap(),
                Fq::from_str(
                    "27613372589672512522307803997948488817865025374001297632527692577079750053456",
                )
                .unwrap(),
                Fq::from_str(
                    "23369674747888778238616865774843237791546925005553032792584302158017141634655",
                )
                .unwrap(),
            ],
            [
                Fq::from_str(
                    "11012136308159330675912474383855146192700147583104742924419195363346115019405",
                )
                .unwrap(),
                Fq::from_str(
                    "20632243971343595216801828590185617698839041744000918292113739726624680548813",
                )
                .unwrap(),
                Fq::from_str(
                    "10530371852841765918702282883445676639977895775479854136871270050807595649710",
                )
                .unwrap(),
            ],
            [
                Fq::from_str(
                    "1610594053831245596683250788274018471388810111366046583216577135605955718023",
                )
                .unwrap(),
                Fq::from_str(
                    "452300846172044702598793611907955884294868639769163388132276731316720796255",
                )
                .unwrap(),
                Fq::from_str(
                    "22297945145153422883128810575530182077542612397826351322358420927950400316504",
                )
                .unwrap(),
            ],
            [
                Fq::from_str(
                    "28212510899948152845929142163236606049756849316851154583029383581129293825706",
                )
                .unwrap(),
                Fq::from_str(
                    "28325924586146971645663587791728624896861517146549428987043066595915712075981",
                )
                .unwrap(),
                Fq::from_str(
                    "23489013325315178311518261165509151135555509351661386106070231815049642443022",
                )
                .unwrap(),
            ],
            [
                Fq::from_str(
                    "10150108696154604591036176090028652090941375062280095655463112192524823306544",
                )
                .unwrap(),
                Fq::from_str(
                    "14935856239824547404885450872472169780177654619496758596151670953532153419587",
                )
                .unwrap(),
                Fq::from_str(
                    "4367251608666794961207658726914177158125339342277880902441218521648798930454",
                )
                .unwrap(),
            ],
            [
                Fq::from_str(
                    "14278046449956534912766622635951826857049583276976844525135170835571509013020",
                )
                .unwrap(),
                Fq::from_str(
                    "11627801940273881243235293875277734806211947530882079339115454640100174268255",
                )
                .unwrap(),
                Fq::from_str(
                    "22853853581419894582873479603685652928885253184240650995805892818180355600894",
                )
                .unwrap(),
            ],
            [
                Fq::from_str(
                    "4405193089432137585625363585733613667088817369599257533888439029942466720878",
                )
                .unwrap(),
                Fq::from_str(
                    "26434497741746827048559732407319982377645052620918789373329661707603241810667",
                )
                .unwrap(),
                Fq::from_str(
                    "23558650878002025381506445692526977061352711282820117441110868042756853707843",
                )
                .unwrap(),
            ],
            [
                Fq::from_str(
                    "27427423077748345654234924309581695092179468167973406115643356520054395647078",
                )
                .unwrap(),
                Fq::from_str(
                    "17585801825757985265979208086560185342609289319992678737491966299829354657891",
                )
                .unwrap(),
                Fq::from_str(
                    "22079131836316223121286612953926945430480043835170303484162677394496378207190",
                )
                .unwrap(),
            ],
            [
                Fq::from_str(
                    "20126865597655889981803452476686954944892814234259869552204215672627920656068",
                )
                .unwrap(),
                Fq::from_str(
                    "5591585339015997308682985123056479221565470335707041924016523106405300562835",
                )
                .unwrap(),
                Fq::from_str(
                    "9422316572086279209843572429137982927615080330725918371521370800874341571474",
                )
                .unwrap(),
            ],
            [
                Fq::from_str(
                    "2735677349719528139570614238939713941030373684882307164259316901880218894412",
                )
                .unwrap(),
                Fq::from_str(
                    "16229147459127626384090303399894157248853232127961182470501666316464149067069",
                )
                .unwrap(),
                Fq::from_str(
                    "17151067888069760812629817914442472623785916486309268828873486698948911058517",
                )
                .unwrap(),
            ],
            [
                Fq::from_str(
                    "13833972862865550568348750465964022581895521701070662509936215512761615491351",
                )
                .unwrap(),
                Fq::from_str(
                    "9624679817699048440664645568701817641311119158936258215534754849666144699339",
                )
                .unwrap(),
                Fq::from_str(
                    "10273179847163882031630140477902608240997857384703412878925192706057610103613",
                )
                .unwrap(),
            ],
            [
                Fq::from_str(
                    "3172037826021850467928085880043492158321918352296515787555947245998877188849",
                )
                .unwrap(),
                Fq::from_str(
                    "28890802281119993101506497911757988639840653958256859430239635494708187190915",
                )
                .unwrap(),
                Fq::from_str(
                    "23496953773368274731821824281559682992786773767847557735733251263969009271239",
                )
                .unwrap(),
            ],
            [
                Fq::from_str(
                    "1509044982655321910215442389040863370827049078919961070795919190828975736187",
                )
                .unwrap(),
                Fq::from_str(
                    "13927172650979098916742472053302036482743492746437467103459483008024082210879",
                )
                .unwrap(),
                Fq::from_str(
                    "17248379591027039069313293591621091031164062825086122980769287846951363066520",
                )
                .unwrap(),
            ],
            [
                Fq::from_str(
                    "11350333545134487336540967650634077894516131586708748380417042089147896079201",
                )
                .unwrap(),
                Fq::from_str(
                    "639497848254405996993150855123515463224731962182127668267769103213580096582",
                )
                .unwrap(),
                Fq::from_str(
                    "24528361599642320451530127347946798949257664936307333999618279589325586618880",
                )
                .unwrap(),
            ],
            [
                Fq::from_str(
                    "8217015496508457685301448884203977810298711070026260090660268003968421268717",
                )
                .unwrap(),
                Fq::from_str(
                    "6703444480721420507060701216472376128524677965704475494357937059812166295103",
                )
                .unwrap(),
                Fq::from_str(
                    "8051365375874262471960241848873604339195556527603956582828833313772444122472",
                )
                .unwrap(),
            ],
            [
                Fq::from_str(
                    "10412735174026641936105532807659667596947675372330827493649954160029449767122",
                )
                .unwrap(),
                Fq::from_str(
                    "8447576362386697729021229138353952824970707645851763166490398451107606293885",
                )
                .unwrap(),
                Fq::from_str(
                    "4802965296970904162106502573136505305073730277702271660292532219583823320181",
                )
                .unwrap(),
            ],
            [
                Fq::from_str(
                    "3244354881334856885788568976540712586633556478250043997221528214026130052269",
                )
                .unwrap(),
                Fq::from_str(
                    "817270901440592571623549787267103386561304980129799240746702119063425010300",
                )
                .unwrap(),
                Fq::from_str(
                    "6566338353152134577893356938981496347522747926131278635019050445923229718029",
                )
                .unwrap(),
            ],
            [
                Fq::from_str(
                    "4854521709622003124815206874897232905514824969466266873443062691298769768277",
                )
                .unwrap(),
                Fq::from_str(
                    "12830134034124699064152980183243986699241944691238427861184919962819448276943",
                )
                .unwrap(),
                Fq::from_str(
                    "24309439157688106320977023683093060719537142150089588950480669629964661236785",
                )
                .unwrap(),
            ],
            [
                Fq::from_str(
                    "1853791709949511636795588377016980571084333441972847324139062389997895453872",
                )
                .unwrap(),
                Fq::from_str(
                    "11399505004623970417786749745036397690793259153591025248188283534764565207306",
                )
                .unwrap(),
                Fq::from_str(
                    "6280235834578097246976697944083887557501831809932305676532914637669922657807",
                )
                .unwrap(),
            ],
            [
                Fq::from_str(
                    "1516294190187225192808636261678393666537186816904214776860202535671714230097",
                )
                .unwrap(),
                Fq::from_str(
                    "5835813607391397757416951433662507638966861369364000865214031356023042341328",
                )
                .unwrap(),
                Fq::from_str(
                    "25777313996516799380163546628133415256678997511953860435781885414872422583905",
                )
                .unwrap(),
            ],
            [
                Fq::from_str(
                    "9749298878960864917089442034293906589697892682402070689770627645324414273893",
                )
                .unwrap(),
                Fq::from_str(
                    "19986612197193695239708718365565978831607994386509967951279410162135133793419",
                )
                .unwrap(),
                Fq::from_str(
                    "5020585421647265067890838871263925730422335215511670656851726444447972642755",
                )
                .unwrap(),
            ],
            [
                Fq::from_str(
                    "7256822974971238434100017358319972368738353570339258522235883585691301791128",
                )
                .unwrap(),
                Fq::from_str(
                    "9789139064283320903202623693175751994730652446378861671859478926598420184293",
                )
                .unwrap(),
                Fq::from_str(
                    "19283468246375057076525422714896652730563534118070235174488237489890270899533",
                )
                .unwrap(),
            ],
            [
                Fq::from_str(
                    "11487321478704551489982188818171823402443882145686911658585221913500937481156",
                )
                .unwrap(),
                Fq::from_str(
                    "16513958012405406860890342996091255867910990589443610357743227675107758695101",
                )
                .unwrap(),
                Fq::from_str(
                    "24764429351173766080138047602436205744310671344674490826288279531917797263231",
                )
                .unwrap(),
            ],
            [
                Fq::from_str(
                    "8256258316375000496541664568891934707113720493937218096466691600593595285909",
                )
                .unwrap(),
                Fq::from_str(
                    "26919625894863883593081175799908601863265420311251948374988589188905317081443",
                )
                .unwrap(),
                Fq::from_str(
                    "10135851848127171199130812615581006825969108287418884763125596866448544567342",
                )
                .unwrap(),
            ],
            [
                Fq::from_str(
                    "17567146349912867622479843655652582453162587996421871126612027345809646551661",
                )
                .unwrap(),
                Fq::from_str(
                    "2524802431860351616270075327416865184018211992251290134350377936184047953453",
                )
                .unwrap(),
                Fq::from_str(
                    "3417609143162661859785838333493682460709943782149216513733553607075915176256",
                )
                .unwrap(),
            ],
            [
                Fq::from_str(
                    "6906455011502599710165862205505812668908382042647994457156780865092846286493",
                )
                .unwrap(),
                Fq::from_str(
                    "21042097659487317081899343674473811663642293019125869396575405454328274948985",
                )
                .unwrap(),
                Fq::from_str(
                    "25222370053690749913129090298406788520061040938312366403907461864202905656238",
                )
                .unwrap(),
            ],
            [
                Fq::from_str(
                    "18933201791079410639949505893100361911334261775545573219434897335758052335005",
                )
                .unwrap(),
                Fq::from_str(
                    "14503331557348715387048413780116585195932777696828173626366829282421027153184",
                )
                .unwrap(),
                Fq::from_str(
                    "3558781473325529402549318082942465709639711182863041375748599816583729962116",
                )
                .unwrap(),
            ],
            [
                Fq::from_str(
                    "23932570601084008621895097434501731960424360312878373523779451810455362953625",
                )
                .unwrap(),
                Fq::from_str(
                    "13286131463754478912858022007443470896920464302917391606059553157137090717219",
                )
                .unwrap(),
                Fq::from_str(
                    "9969435194445819847988134248075866286921574284754991873902788928171429847506",
                )
                .unwrap(),
            ],
            [
                Fq::from_str(
                    "10821551500865029673311799086099720530496516676117927814621168667836737594374",
                )
                .unwrap(),
                Fq::from_str(
                    "57689402905128519605376551862931564078571458212398163192591670282543962941",
                )
                .unwrap(),
                Fq::from_str(
                    "4484359679395800410695081358212522306960518636189521201445105538223906998486",
                )
                .unwrap(),
            ],
        ],
    }
}

/// the fp sponge params
pub fn static_fq_params() -> &'static ArithmeticSpongeParams<Fq> {
    static PARAMS: Lazy<ArithmeticSpongeParams<Fq>> = Lazy::new(make_fq_params);
    &PARAMS
}

pub trait SpongeConstants {
    const SPONGE_CAPACITY: usize = 1;
    const SPONGE_WIDTH: usize = 3;
    const SPONGE_RATE: usize = 2;
    const PERM_ROUNDS_FULL: usize;
    const PERM_ROUNDS_PARTIAL: usize;
    const PERM_HALF_ROUNDS_FULL: usize;
    const PERM_SBOX: u32;
    const PERM_FULL_MDS: bool;
    const PERM_INITIAL_ARK: bool;
}

// #[derive(Clone)]
// pub struct PlonkSpongeConstantsLegacy {}

// impl SpongeConstants for PlonkSpongeConstantsLegacy {
//     const SPONGE_CAPACITY: usize = 1;
//     const SPONGE_WIDTH: usize = 3;
//     const SPONGE_RATE: usize = 2;
//     const PERM_ROUNDS_FULL: usize = 63;
//     const PERM_ROUNDS_PARTIAL: usize = 0;
//     const PERM_HALF_ROUNDS_FULL: usize = 0;
//     const PERM_SBOX: u32 = 5;
//     const PERM_FULL_MDS: bool = true;
//     const PERM_INITIAL_ARK: bool = true;
// }

#[derive(Clone)]
pub struct PlonkSpongeConstantsKimchi {}

impl SpongeConstants for PlonkSpongeConstantsKimchi {
    const SPONGE_CAPACITY: usize = 1;
    const SPONGE_WIDTH: usize = 3;
    const SPONGE_RATE: usize = 2;
    const PERM_ROUNDS_FULL: usize = 55;
    const PERM_ROUNDS_PARTIAL: usize = 0;
    const PERM_HALF_ROUNDS_FULL: usize = 0;
    const PERM_SBOX: u32 = 7;
    const PERM_FULL_MDS: bool = true;
    const PERM_INITIAL_ARK: bool = false;
}

#[allow(clippy::extra_unused_type_parameters)]
#[inline(never)]
fn apply_mds_matrix<F: Field, SC: SpongeConstants>(
    params: &ArithmeticSpongeParams<F>,
    state: &[F],
) -> [F; 3] {
    let mut new_state = [F::zero(); 3];

    for (i, sub_params) in params.mds.iter().enumerate() {
        for (state, param) in state.iter().zip(sub_params) {
            new_state[i].add_assign(*param * state);
        }
    }

    new_state
}

#[inline(never)]
pub fn full_round<F: Field, SC: SpongeConstants>(
    params: &ArithmeticSpongeParams<F>,
    state: &mut [F; 3],
    r: usize,
) {
    for state_i in state.iter_mut() {
        *state_i = sbox::<F, SC>(*state_i);
    }
    *state = apply_mds_matrix::<F, SC>(params, state);
    for (i, x) in params.round_constants[r].iter().enumerate() {
        state[i].add_assign(x);
    }
}

#[inline(never)]
pub fn poseidon_block_cipher<F: Field, SC: SpongeConstants>(
    params: &ArithmeticSpongeParams<F>,
    state: &mut [F; 3],
) {
    for r in 0..SC::PERM_ROUNDS_FULL {
        full_round::<F, SC>(params, state, r);
    }
}

/// Cryptographic sponge interface - for hashing an arbitrary amount of
/// data into one or more field elements
pub trait Sponge<Input: Field, Digest> {
    /// Create a new cryptographic sponge using arithmetic sponge `params`
    fn new(params: &'static ArithmeticSpongeParams<Input>) -> Self;

    /// Absorb an array of field elements `x`
    fn absorb(&mut self, x: &[Input]);

    /// Squeeze an output from the sponge
    fn squeeze(&mut self) -> Digest;

    /// Reset the sponge back to its initial state (as if it were just created)
    fn reset(&mut self);
}

#[inline(never)]
pub fn sbox<F: Field, SC: SpongeConstants>(mut x: F) -> F {
    // Faster than calling x.pow(SC::PERM_SBOX)
    let a = x;
    for _ in 0..SC::PERM_SBOX - 1 {
        x.mul_assign(a);
    }
    x

    // x.pow([SC::PERM_SBOX as u64])
}

#[derive(Clone, Debug)]
pub enum SpongeState {
    Absorbed(usize),
    Squeezed(usize),
}

// #[derive(Clone, Serialize, Deserialize, Debug)]
pub struct ArithmeticSpongeParams<F: Field> {
    pub round_constants: [[F; 3]; 55],
    pub mds: [[F; 3]; 3],
    // pub mds: Vec<Vec<F>>,
}

pub trait SpongeParamsForField<F: Field> {
    fn get_params() -> &'static ArithmeticSpongeParams<F>;
    /// Params from `proof-systems`
    /// TODO: Dedup this
    fn get_params2() -> &'static mina_poseidon::poseidon::ArithmeticSpongeParams<F>;
}

impl SpongeParamsForField<Fp> for Fp {
    fn get_params() -> &'static ArithmeticSpongeParams<Fp> {
        static_params()
    }

    fn get_params2() -> &'static mina_poseidon::poseidon::ArithmeticSpongeParams<Fp> {
        use mina_poseidon::pasta::fp_kimchi::static_params;
        static_params()
    }
}

impl SpongeParamsForField<Fq> for Fq {
    fn get_params() -> &'static ArithmeticSpongeParams<Fq> {
        static_fq_params()
    }

    fn get_params2() -> &'static mina_poseidon::poseidon::ArithmeticSpongeParams<Fq> {
        use mina_poseidon::pasta::fq_kimchi::static_params;
        static_params()
    }
}

#[derive(Clone)]
pub struct ArithmeticSponge<F: Field, SC: SpongeConstants> {
    pub sponge_state: SpongeState,
    rate: usize,
    // TODO(mimoo: an array enforcing the width is better no? or at least an assert somewhere)
    pub state: [F; 3],
    // pub state: Vec<F>,
    // tmp_state: Vec<Vec<F>>,
    params: &'static ArithmeticSpongeParams<F>,
    pub constants: std::marker::PhantomData<SC>,
}

impl<F: Field, SC: SpongeConstants> ArithmeticSponge<F, SC> {
    #[inline(never)]
    pub fn full_round(&mut self, r: usize) {
        full_round::<F, SC>(self.params, &mut self.state, r);
    }

    #[inline(never)]
    fn poseidon_block_cipher(&mut self) {
        poseidon_block_cipher::<F, SC>(self.params, &mut self.state);
    }
}

impl<F: Field, SC: SpongeConstants> Sponge<F, F> for ArithmeticSponge<F, SC> {
    fn new(params: &'static ArithmeticSpongeParams<F>) -> ArithmeticSponge<F, SC> {
        // let capacity = SC::SPONGE_CAPACITY;
        let rate = SC::SPONGE_RATE;

        // let mut state = Vec::with_capacity(capacity + rate);

        // for _ in 0..(capacity + rate) {
        //     state.push(F::zero());
        // }

        // let mut tmp_state = Vec::with_capacity(16);

        ArithmeticSponge {
            state: [F::zero(); 3],
            rate,
            sponge_state: SpongeState::Absorbed(0),
            params,
            constants: std::marker::PhantomData,
            // tmp_state,
        }
    }

    #[inline(never)]
    fn absorb(&mut self, x: &[F]) {
        for x in x.iter() {
            match self.sponge_state {
                SpongeState::Absorbed(n) => {
                    if n == self.rate {
                        self.poseidon_block_cipher();
                        self.sponge_state = SpongeState::Absorbed(1);
                        self.state[0].add_assign(x);
                    } else {
                        self.sponge_state = SpongeState::Absorbed(n + 1);
                        self.state[n].add_assign(x);
                    }
                }
                SpongeState::Squeezed(_n) => {
                    self.state[0].add_assign(x);
                    self.sponge_state = SpongeState::Absorbed(1);
                }
            }
        }
    }

    #[inline(never)]
    fn squeeze(&mut self) -> F {
        // assert_eq!(self.state.len(), 3);
        // elog!("NSTATE={:?}", self.state.len());
        match self.sponge_state {
            SpongeState::Squeezed(n) => {
                if n == self.rate {
                    self.poseidon_block_cipher();
                    self.sponge_state = SpongeState::Squeezed(1);
                    self.state[0]
                } else {
                    self.sponge_state = SpongeState::Squeezed(n + 1);
                    self.state[n]
                }
            }
            SpongeState::Absorbed(_n) => {
                self.poseidon_block_cipher();
                self.sponge_state = SpongeState::Squeezed(1);
                self.state[0]
            }
        }
    }

    fn reset(&mut self) {
        todo!()
        // self.state = vec![F::zero(); self.state.len()];
        // self.sponge_state = SpongeState::Absorbed(0);
    }
}
